#include "log.hpp"

void bench(const string& logger_name,size_t thr_count,size_t msg_count,size_t msg_len)
{
    //1.获取日志器
    Logger::ptr logger = getLogger(logger_name);
    if(logger.get()==nullptr)
    {
        return ;
    }
    cout<<"测试日志"<<msg_count<<" 条, 总大小： "<<(msg_count*msg_len)/1024<<"KB"<<endl;

    //2.组织指定长度的日志消息
    string msg(msg_len-1,'A');
    vector<thread> threads;
    vector<double> cost_arry(thr_count);
    size_t msg_per_thr = msg_count/thr_count;//每个线程要输出的日志数量
    for(int i=0;i<thr_count;++i)
    {
        threads.emplace_back([&,i](){
            auto start = chrono::high_resolution_clock::now();

            for(int j=0;j<msg_per_thr;++j)
            {
                logger->fatal("%s",msg.c_str());
            }

            auto end = chrono::high_resolution_clock::now();
            chrono::duration<double> cost = end-start;
            cost_arry[i] = cost.count();
            cout<<"\t线程"<<i<<":"<<"\t输出数量:"<<msg_per_thr<<",耗时:"<<cost.count()<<endl;
        });
    }

    for(int i=0;i<thr_count;++i)
    {
        threads[i].join();
    }
    //计算总耗时，线程是并发的，耗时最高的线程就是总耗时
    double max_cost = cost_arry[0];
    for(int i=0;i<thr_count;++i)
    {
        max_cost = max(max_cost,cost_arry[i]);
    }
    size_t msg_per_sec = msg_count/max_cost;
    size_t size_per_sec = (msg_count*msg_len)/(max_cost*1024);

    cout<<"\t每秒输出日志数量:"<<msg_per_sec<<"条"<<endl;
    cout<<"\t每秒输出日志大小:"<<size_per_sec<<"KB"<<endl;
}   

void sync_bench()
{
    unique_ptr<LoggerBuilder> builder(new GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildLoggerLevel(LogLevel::value::Warn);
    builder->buildFormatter("%m%n");
    builder->buildLoggerType(LoggerType::LOGGER_SYNC);
    builder->buildSink<FileSink>("./logfile/sync.log");
    //builder->buildSink<StdoutSink>();
    builder->build();
    bench("sync_logger",3,1000000,100);
}

void async_bench()
{
    unique_ptr<LoggerBuilder> builder(new GlobalLoggerBuilder());
    builder->buildLoggerName("Async_logger");
    builder->buildLoggerLevel(LogLevel::value::Warn);
    builder->buildFormatter("%m%n");
    builder->buildEnableUnSafeAsync();
    builder->buildLoggerType(LoggerType::LOGGER_ASYNC);
    builder->buildSink<FileSink>("./logfile/Async.log");
    //builder->buildSink<StdoutSink>();
    builder->build();
    bench("Async_logger",5,2000000,100);
}

int main()
{
    async_bench();
    return 0;
}